from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from math import sin, cos, pi
class Turtle:
    def __init__(self, cx=0, cy=0, scaleX=1, scaleY=1):
        self.x = cx
        self.y = cy
        self.pen = True
        self.scaleX = scaleX
        self.scaleY = scaleY
        self.actions = {}
        self.actions['u'] = self.goUp
        self.actions['d'] = self.goDown
        self.actions['l'] = self.goLeft
        self.actions['r'] = self.goRight
        self.actions['_'] = self.penDown
        self.actions['^'] = self.penUp
        self.actions['.'] = self.smallCircle
        self.actions['red'] = self.colorRed
        self.actions['green'] = self.colorGreen
        self.actions['blue'] = self.colorBlue
        self.actions['s'] = self.savePos
        self.actions['b'] = self.goBack
        self.actions['<'] = self.decScale2x
        self.actions['>'] = self.incScale2x
        self.actions['c1'] = self.applyC1
        self.actions['c2'] = self.applyC2
        self.actions['c3'] = self.applyC3

    def draw(self, program):
        for s in program.split():
            if s in self.actions.keys():
                self.actions[s]()
                continue
            print "Turtle: wrong command", s

    def moveTo(self, x, y):
        self.x = x
        self.y = y

    def lineTo(self, x, y):
        glBegin(GL_LINES)
        glVertex3f(self.x, self.y, 0)
        glVertex3f(x, y, 0)
        glEnd()
        self.moveTo(x, y)

    def step(self, dx, dy):
        newx = self.x + dx * self.scaleX
        newy = self.y + dy * self.scaleY
        if self.pen:
            self.lineTo(newx, newy)
        else:
            self.moveTo(newx, newy)

    def goUp(self):
        self.step(0, 1)

    def goDown(self):
        self.step(0, -1)

    def goLeft(self):
        self.step(-1, 0)

    def goRight(self):
        self.step(1, 0)

    def penUp(self):
        self.pen = False

    def penDown(self):
        self.pen = True

    def colorRed(self):
        glColor3f(1, 0, 0)

    def colorGreen(self):
        glColor3f(0, 1, 0)

    def colorBlue(self):
        glColor3f(0, 0, 1)

    def smallCircle(self):
        r = .3
        step = 10 # degrees
        ox, oy = self.x, self.y
        for angle in range(0, 360+step, step):
            angleR = pi * angle/180.
            x = ox + cos(angleR) * self.scaleX
            y = oy + sin(angleR) * self.scaleY
            if angle == 0:
                self.moveTo(x, y)
            else:
                self.lineTo(x, y)
        self.x = ox
        self.y = oy

    def savePos(self):
        self.savedX = self.x
        self.savedY = self.y

    def goBack(self):
        self.x = self.savedX
        self.y = self.savedY

    def decScale2x(self):
        self.scaleX /= 2.
        self.scaleY /= 2.

    def incScale2x(self):
        self.scaleX *= 2.
        self.scaleY *= 2.

    def applyC1(self):
        glColor3f(self.c1[0], self.c1[1], self.c1[2])

    def applyC2(self):
        glColor3f(self.c2[0], self.c2[1], self.c2[2])

    def applyC3(self):
        glColor3f(self.c3[0], self.c3[1], self.c3[2])